package com.ruoyi.accountant.service.impl;

import com.ruoyi.web.core.config.AppConf;
import com.ruoyi.accountant.domain.*;
import com.ruoyi.accountant.mapper.AccountDetailMapper;
import com.ruoyi.accountant.mapper.ReasonDetailMapper;
import com.ruoyi.accountant.mapper.TransactionDetailMapper;
import com.ruoyi.accountant.service.*;
import com.ruoyi.web.web.form.IncomeForm;
import com.ruoyi.web.web.form.PayForm;
import com.ruoyi.web.web.form.TransactionDetailListForm;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class TransactionDetailServiceImpl implements TransactionDetailService {


    @Autowired
    private TransactionDetailMapper transactionDetailMapper;

    @Autowired
    private BalanceService balanceService;

    @Autowired
    private AccountDetailMapper accountDetailMapper;

    @Autowired
    private ReasonDetailMapper reasonDetailMapper;

    @Autowired
    private CurrencyService currencyService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private InaccountService inaccountService;

    // @Override
    public List<TransactionDetail> findAll() {
        return transactionDetailMapper.selectByExample(null);
    }

    @Override
    public List<TransactionDetail> findAllByForm(TransactionDetailListForm transactionDetailListForm) {
        PageHelper.startPage(transactionDetailListForm.getPage() - 1, transactionDetailListForm.getRows(), "createtime desc");
        TransactionDetailExample transactionDetailExample = new TransactionDetailExample();
        TransactionDetailExample.Criteria criteria = transactionDetailExample.createCriteria();
        criteria.andDeletedEqualTo(AppConf.OFF);
        if (transactionDetailListForm.isTransactionDateOn()) {
            criteria.andTransactionDateGreaterThanOrEqualTo(transactionDetailListForm.getTransactionStartDate())
                    .andTransactionDateLessThanOrEqualTo(transactionDetailListForm.getTransactionEndDate());
        }

        //凭证日期
        if (transactionDetailListForm.isProofDateOn()) {
            criteria.andProofDateGreaterThanOrEqualTo(transactionDetailListForm.getProofStartDate())
                    .andProofDateLessThanOrEqualTo(transactionDetailListForm.getProofEndDate());
        }

        // 交易类别
        if (transactionDetailListForm.getTransactionType() != null && !transactionDetailListForm.getTransactionType().equals("不限")) {
            criteria.andDtypeEqualTo(transactionDetailListForm.getTransactionType());
        }

        // 收支原因
        if (transactionDetailListForm.getReason() != null && transactionDetailListForm.getReason() != -1L) {
            criteria.andOfReasonEqualTo(transactionDetailListForm.getReason());
        }

        //综合
        if ((transactionDetailListForm.getOther() != null && !StringUtils.isEmpty(transactionDetailListForm.getOther()))) {
            //对象 标签 发票号码 备注

            criteria.andObjectLike("%" + transactionDetailListForm.getOther() + "%");
            criteria.andTagLike("%" + transactionDetailListForm.getOther() + "%");
            criteria.andInvoiceLike("%" + transactionDetailListForm.getOther() + "%");
            criteria.andCommentLike("%" + transactionDetailListForm.getOther() + "%");
        }

        // 所属账户
        if (transactionDetailListForm.getOfAccount() != null && transactionDetailListForm.getOfAccount() != -1) {
            criteria.andOfAccountEqualTo(transactionDetailListForm.getOfAccount());
        }

        List<TransactionDetail> transactionDetails = transactionDetailMapper.selectByExample(transactionDetailExample);
        PageInfo<TransactionDetail> pageInfo = new PageInfo<>(transactionDetails);


        return transactionDetails;
    }


    @Override
    public void deleteById(Long tid) {
        // 如果是收入，将加入的钱减去
        // 如果是支出，将减去的钱加到账户上

        TransactionDetail transactionDetail = transactionDetailMapper.selectByPrimaryKey(tid);
        Account ofAccount = transactionDetail.getOfAccountObject();

        String dtype = transactionDetail.getDtype();
        if (dtype.equals("收入")) {
            Balance balance = balanceService.findByOfAccountAndOfCurrency(ofAccount.getAid(), transactionDetail.getOfCurrencyObject().getCid());
            balance.subtract(transactionDetail.getMoney());
            balanceService.save(balance);
        } else if (dtype.equals("支出")) {
            if (!transactionDetail.getDtype().equals("应付款")) { // 退回
                Balance balance = balanceService.findByOfAccountAndOfCurrency(ofAccount.getAid(), transactionDetail.getOfCurrencyObject().getCid());
                balance.add(transactionDetail.getMoney());
                balanceService.save(balance);
            }
        } else if (dtype.equals("转移")) {
            // 删除交易记录，将钱退回，并且删除待入账
            Inaccount inaccount = inaccountService.findById(transactionDetail.getIid());
            BigDecimal ret = inaccount.getOutaccountMoney().add(new BigDecimal(inaccount.getServiceCharge()));
            Balance balance = balanceService.findByOfAccountAndOfCurrency(inaccount.getOutaccount(), inaccount.getOutaccountCurrency());
            balance.add(ret);
            balanceService.save(balance);

            // 删除inaccount
            inaccountService.deleteById(inaccount.getIid());

            // 删除交易记录
            transactionDetailMapper.deleteByPrimaryKey(transactionDetail.getTid());
            // 删除账户交易记录
            accountDetailMapper.deleteByPrimaryKey(transactionDetail.getAccountDetailId());

            return;
        } else if (transactionDetail.getDtype().equals("应收款")) {
            // 如果有订金则退回订金，如果没有则删除
            if (transactionDetail.getWithDeposit() == AppConf.ON) {
                TransactionDetail depositDetail = transactionDetailMapper.selectByPrimaryKey(transactionDetail.getDepositId());
                Balance balance = balanceService.findByOfAccountAndOfCurrency(ofAccount.getAid(), transactionDetail.getOfCurrencyObject().getCid());
                balance.subtract(depositDetail.getMoney());
                balanceService.save(balance);

                // 刪除
                depositDetail.setDeleted(AppConf.ON); // 标记删除
                transactionDetailMapper.updateByPrimaryKeySelective(depositDetail);


                AccountDetail accountDetail = accountDetailMapper.selectByPrimaryKey(depositDetail.getAccountDetailId());
                ReasonDetail reasonDetail = reasonDetailMapper.selectByPrimaryKey(depositDetail.getReasonDetailId());

                transactionDetail.setDeleted(AppConf.ON); // 标记删除
                transactionDetail.setDeletedDate(new Date());

                accountDetail.setDeleted(AppConf.ON);
                reasonDetail.setDeleted(AppConf.ON);

                accountDetailMapper.insert(accountDetail);
                reasonDetailMapper.updateByPrimaryKeySelective(reasonDetail);
                transactionDetailMapper.updateByPrimaryKeySelective(transactionDetail);

                return;
            }
        } else if (dtype.equals("应付款")) { // 直接删除
            transactionDetailMapper.deleteByPrimaryKey(transactionDetail.getTid());
            return;
        }

        AccountDetail accountDetail = accountDetailMapper.selectByPrimaryKey(transactionDetail.getAccountDetailId());
        ReasonDetail reasonDetail = reasonDetailMapper.selectByPrimaryKey(transactionDetail.getReasonDetailId());

        transactionDetail.setDeleted(AppConf.ON); // 标记删除
        transactionDetail.setDeletedDate(new Date());

        accountDetail.setDeleted(AppConf.ON);
        reasonDetail.setDeleted(AppConf.ON);

        accountDetailMapper.insert(accountDetail);
        reasonDetailMapper.updateByPrimaryKeySelective(reasonDetail);
        transactionDetailMapper.updateByPrimaryKeySelective(transactionDetail);
    }

    @Override
    public List<TransactionDetail> findDeleted() {
        TransactionDetailExample transactionDetailExample = new TransactionDetailExample();
        transactionDetailExample.createCriteria().andDeletedEqualTo(AppConf.ON);
        return transactionDetailMapper.selectByExample(transactionDetailExample);
    }

    @Override
    public void recover(Long tid) {
        TransactionDetail transactionDetail = transactionDetailMapper.selectByPrimaryKey(tid);
        AccountDetail accountDetail = accountDetailMapper.selectByPrimaryKey(transactionDetail.getAccountDetailId());
        ReasonDetail reasonDetail = reasonDetailMapper.selectByPrimaryKey(transactionDetail.getReasonDetailId());

        transactionDetail.setDeleted(AppConf.OFF);
        accountDetail.setDeleted(AppConf.OFF);
        reasonDetail.setDeleted(AppConf.OFF);

        accountDetailMapper.insert(accountDetail);
        reasonDetailMapper.updateByPrimaryKeySelective(reasonDetail);
        transactionDetailMapper.updateByPrimaryKeySelective(transactionDetail);


        // 如果是收入将金额加入到账户

        // 如果是支出将金额重新减出账户
        String dtype = transactionDetail.getDtype();
        Balance balance = balanceService.findByOfAccountAndOfCurrency(transactionDetail.getOfAccountObject().getAid(), transactionDetail.getOfCurrencyObject().getCid());
        if (dtype.equals("收入")) {
            balance.add(transactionDetail.getMoney());
        } else if (dtype.equals("支出")) {
            balance.subtract(transactionDetail.getMoney());
        }
        balanceService.save(balance);
    }

    @Override
    public TransactionDetail findById(Long tid) {
        return transactionDetailMapper.selectByPrimaryKey(tid);
    }

    @Override
    public void updateByForm(TransactionDetail form) {
        TransactionDetail transactionDetail = transactionDetailMapper.selectByPrimaryKey(form.getTid());
        AccountDetail accountDetail = accountDetailMapper.selectByPrimaryKey(transactionDetail.getAccountDetailId());
        ReasonDetail reasonDetail = reasonDetailMapper.selectByPrimaryKey(transactionDetail.getReasonDetailId());
        System.out.println(transactionDetail.getOfAccountObject().getAid());
        System.out.println(transactionDetail.getOfCurrencyObject().getCid());
        System.out.println(transactionDetail);

        // 余额更改
        // 如果收入
        if (transactionDetail.getOfAccountObject().getAid() != null && transactionDetail.getOfCurrencyObject().getCid() != null) {
            Balance balance = balanceService.findByOfAccountAndOfCurrency(transactionDetail.getOfAccountObject().getAid(), transactionDetail.getOfCurrencyObject().getCid());
            if (transactionDetail.getDtype().equals("收入")) {
                if (balance.getBalance().min(form.getMoney()).equals(form.getMoney())) { //新增的收入多
                    balance.add(form.getMoney().subtract(balance.getBalance()));
                } else {
                    balance.subtract(balance.getBalance().subtract(form.getMoney())); // 新增的收入少
                }
            } else if (transactionDetail.getDtype().equals("支出")) {
                if (balance.getBalance().min(form.getMoney()).equals(form.getMoney())) { //新增的支出多
                    balance.subtract(form.getMoney().subtract(balance.getBalance()));
                } else {
                    balance.add(balance.getBalance().subtract(form.getMoney())); // 新增的收入少
                }
            }
            balanceService.updata(balance);
        }


        // 收付日期
        // 凭证日期
        // 交易金额
        // 附注说明
        // 对象
        // 标签
        // 发票号码
        transactionDetail.setTransactionDate(form.getTransactionDate());
        transactionDetail.setProofDate(form.getProofDate());
        transactionDetail.setMoney(form.getMoney());
        transactionDetail.setComment(form.getComment());
        transactionDetail.setObject(form.getObject());
        transactionDetail.setTag(form.getTag());
        transactionDetail.setInvoice(form.getInvoice());

        accountDetail.setCreatetime(new Timestamp(form.getTransactionDate().getTime()));
        accountDetail.setProofDate(form.getProofDate());

        if (transactionDetail.getDtype().equals("收入")) {
            accountDetail.setInmoney(form.getMoney());
        } else if (transactionDetail.getDtype().equals("支出")) {
            accountDetail.setOutmoney(form.getMoney());
        }
        accountDetail.setComment(form.getComment());
        accountDetail.setObject(form.getObject());
        accountDetail.setTag(form.getTag());


        reasonDetail.setCreatetime(new Timestamp(form.getTransactionDate().getTime()));
        if (transactionDetail.getDtype().equals("收入")) {
            reasonDetail.setCreditorMoney(form.getMoney());
        } else if (transactionDetail.getDtype().equals("支出")) {
            reasonDetail.setDebtorMoney(form.getMoney());
        }
        reasonDetail.setComment(form.getComment());
        reasonDetail.setObject(form.getObject());
        reasonDetail.setTag(form.getTag());
        reasonDetail.setInvoice(form.getInvoice());

        accountDetailMapper.updateByPrimaryKeySelective(accountDetail);
        reasonDetailMapper.updateByPrimaryKeySelective(reasonDetail);
        transactionDetailMapper.updateByPrimaryKeySelective(transactionDetail);
    }

    @Override
    public int deleteOverDeletedDays() {
        //todo 要改
//        List<TransactionDetail> transactionDetailList = transactionDetailMapper.findOverDeletedDays(AppConf.SAVE_DELETED_TRANSACTION_DETAIL_DAY);
        List<TransactionDetail> transactionDetailList = null;
        for (TransactionDetail transactionDetail : transactionDetailList) {
            transactionDetailMapper.deleteByPrimaryKey(transactionDetail.getTid());
            if (transactionDetail.getAccountDetailId() != null)
                accountDetailMapper.deleteByPrimaryKey(transactionDetail.getAccountDetailId());
            if (transactionDetail.getReasonDetailId() != null)
                accountDetailMapper.deleteByPrimaryKey(transactionDetail.getReasonDetailId());
        }
        return transactionDetailList.size();
    }

    @Override
    public void finish(Long tid) {
        TransactionDetail transactionDetail = transactionDetailMapper.selectByPrimaryKey(tid);
        if (transactionDetail.getDtype().equals("应收款")) {
            IncomeForm incomeForm = new IncomeForm();

            incomeForm.setAccount(transactionDetail.getOfAccountObject().getAid());
            incomeForm.setTransactionType("非同日收入");
            incomeForm.setCurrency(transactionDetail.getOfCurrencyObject().getCid());
            incomeForm.setReasonId(transactionDetail.getOfReasonObject().getRid());
            incomeForm.setObject(transactionDetail.getObject());
            incomeForm.setMoney(transactionDetail.getMoney().doubleValue());
            incomeForm.setComment(transactionDetail.getComment());
            incomeForm.setTag(transactionDetail.getTag());
            incomeForm.setAttachment(transactionDetail.getAttachment());
            incomeForm.setInvoice(transactionDetail.getInvoice());
            incomeForm.setIncomeDate(new Date());
            incomeForm.setProofDate(transactionDetail.getProofDate());
            incomeForm.setServiceCharge(transactionDetail.getServiceCharge());
            incomeForm.setTaxRateType(transactionDetail.getTaxRateType());
            incomeForm.setTaxRate(transactionDetail.getTaxRate());

            // 设置名称
            incomeForm.setCurrencyName(currencyService.findById(incomeForm.getCurrency()).getEnName());

            accountService.income(incomeForm);

            // 如果是有订金类的应收款，删除此记录
            if (transactionDetail.getWithDeposit() == AppConf.ON) {
                transactionDetailMapper.deleteByPrimaryKey(transactionDetail.getTid());
                return;
            } else {
                transactionDetail.setDeleted(AppConf.ON);
            }
        } else if (transactionDetail.getDtype().equals("应付款")) {
            //TODO 这里需要完成
            PayForm payForm = new PayForm();
            payForm.setAccount(transactionDetail.getOfAccountObject().getAid());
            payForm.setTransactionType("非同日支出");
            payForm.setCurrency(transactionDetail.getOfCurrencyObject().getCid());
            payForm.setReasonId(transactionDetail.getOfReasonObject().getRid());
            payForm.setObject(transactionDetail.getObject());
            payForm.setMoney(transactionDetail.getMoney().doubleValue());
            payForm.setComment(transactionDetail.getComment());
            payForm.setTag(transactionDetail.getTag());
            payForm.setAttachment(transactionDetail.getAttachment());
            payForm.setPayDate(new Date());
            payForm.setProofDate(transactionDetail.getProofDate());
            payForm.setServiceCharge(transactionDetail.getServiceCharge());
            payForm.setTaxRateType(transactionDetail.getTaxRateType());
            payForm.setTaxRate(transactionDetail.getTaxRate());

            accountService.pay(payForm);
            transactionDetail.setDeleted(AppConf.ON);
        } else if (transactionDetail.getDtype().equals("转移")) { // 直接到账
            inaccountService.finish(transactionDetail.getIid());
        }

        transactionDetailMapper.updateByPrimaryKeySelective(transactionDetail);
    }

}
